package al.xc.wxsession.aop;

import al.xc.common.exception.RequestDecodeException;
import al.xc.common.exception.ResultCodeDefine;
import al.xc.common.middleware.ContextHolder;
import al.xc.data.dto.SessionInfo;
import al.xc.service.ITokenService;
import al.xc.springboot.aop.ITokenVerifier;
import al.xc.springboot.aop.ParamValidate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


@Component
@Scope("singleton")
@Slf4j
public class TokenVerifierImpl implements ITokenVerifier {

    private final static String authorHeader = "XC_Authorization";

    @Autowired
    private ITokenService tokenService;

    /**
     * 验证
     * @param validate
     * @throws Exception
     */
    @Override
    public void verify(ParamValidate validate) throws Exception {
        if (null == validate || 0 == validate.author()) {
            ContextHolder.remove(ContextHolder.USER_TOKEN);
            return;
        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader(authorHeader);
        if (null == token) {
            if (1 == validate.author()) {
                throw new RequestDecodeException(ResultCodeDefine.ERROR_TOKEN, "需要设置鉴权信息头: "+ authorHeader);
            }
            ContextHolder.remove(ContextHolder.USER_TOKEN);
            return;
        }
        SessionInfo session = tokenService.find(token);
        if (null == session) {
            throw new RequestDecodeException(ResultCodeDefine.ERROR_TOKEN, "鉴权失败 不存在");
        }
        if (!session.getToken().equals(token)) {
            throw new RequestDecodeException(ResultCodeDefine.ERROR_TOKEN, "鉴权失败 已失效");
        }
        ContextHolder.put(ContextHolder.USER_TOKEN, session);
    }
}
